package sample.server;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Hashtable;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;

import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.google.inject.name.Named;

import gwtupload.server.UploadAction;
import gwtupload.server.exceptions.UploadActionException;
import gwtupload.shared.UConsts;

@Singleton
public class UploadServlet extends UploadAction
{
  private String clientRootDir;

  @Inject
  public UploadServlet(@Named("dir.clientroot") String clientRootDir) {
    super();
    this.clientRootDir = clientRootDir;
  }

  private static final long serialVersionUID = 1L;

  Hashtable<String, String> receivedContentTypes =
      new Hashtable<String, String>();
  /**
   * Maintain a list with received files and their content types.
   */
  Hashtable<String, File> receivedFiles = new Hashtable<String, File>();

  private File computeFilePath(String clientCode, String filename) {
	  // TODO -- fix this shit... should use: 
	  // @see sample.shared.FileExtensions;
    String filenamelc = filename.toLowerCase();
    String type = "Other";
    if (filenamelc.contains(".doc") || filenamelc.contains(".pdf")
        || filenamelc.contains(".txt")) type = "Word";
    if (filenamelc.contains(".xls")) type = "Excel";
    if (filenamelc.contains(".pdf")) type = "PDF";
    if (filenamelc.contains(".msg")) type = "Emails";

    File dir =
        new File(ClientManagerServiceImpl.getFileFromCode(clientRootDir,
            clientCode) + File.separator + type);

    if (!dir.exists())
      throw new UploadActionException("client directory not set up ["
          + dir.toString() + "]");

    File file = new File(dir.toString() + File.separator + filename);
    return file;
  }

  /**
   * Override executeAction to save the received files in a custom place and
   * delete this items from session.
   */
  @Override
  public String executeAction(HttpServletRequest request,
      List<FileItem> sessionFiles) throws UploadActionException
  {
    String response = "";
    String clientCode = null;
    String filename = null;

    for (FileItem item : sessionFiles) {
      if (!item.isFormField()) {
        try {
          if (clientCode == null || clientCode.length() == 0
              || filename == null) continue;

          File file = computeFilePath(clientCode, filename);
          item.write(file);

          /// Save a list with the received files
          receivedFiles.put(item.getFieldName(), file);
          receivedContentTypes.put(item.getFieldName(), item.getContentType());

          /// Send a customized message to the client.
          response += "File saved as " + file.getAbsolutePath();
        }
        catch (Exception e) {
          throw new UploadActionException(e);
        }
      }
      else {
        if ("clientCode".equals(item.getFieldName())) {
          clientCode = item.getString();
        }
        else if ("filename".equals(item.getFieldName())) {
          filename = item.getString();
        }
      }
    }

    /// Remove files from session because we have a copy of them
    removeSessionFileItems(request);

    /// Send your customized message to the client.
    return response;
  }

  /**
   * Get the content of an uploaded file.
   */
  @Override
  public void getUploadedFile(HttpServletRequest request,
      HttpServletResponse response) throws IOException
  {
    String fieldName = request.getParameter(UConsts.PARAM_SHOW);
    File f = receivedFiles.get(fieldName);
    if (f != null) {
      response.setContentType(receivedContentTypes.get(fieldName));
      FileInputStream is = new FileInputStream(f);
      copyFromInputStreamToOutputStream(is, response.getOutputStream());
    }
    else {
      renderXmlResponse(request, response, XML_ERROR_ITEM_NOT_FOUND);
    }
  }

  /**
   * Remove a file when the user sends a delete request.
   */
  @Override
  public void removeItem(HttpServletRequest request, String fieldName)
      throws UploadActionException
  {
    File file = receivedFiles.get(fieldName);
    receivedFiles.remove(fieldName);
    receivedContentTypes.remove(fieldName);
    if (file != null) {
      file.delete();
    }
  }
}